"""
服务定位器，用于管理服务实例和依赖关系
"""
from typing import Dict, Type, TypeVar, Any, Optional
from app.utils.logger import Logger

# 定义泛型类型变量
T = TypeVar('T')


class ServiceLocator:
    """
    服务定位器，用于管理服务实例和依赖关系
    
    使用单例模式实现
    """
    
    # 单例实例
    _instance = None
    
    @classmethod
    def get_instance(cls):
        """
        获取服务定位器实例
        
        @return: 服务定位器实例
        """
        if cls._instance is None:
            cls._instance = ServiceLocator()
        return cls._instance
    
    def __init__(self):
        """
        初始化服务定位器
        """
        # 确保只有一个实例
        if ServiceLocator._instance is not None:
            raise RuntimeError("ServiceLocator 是单例类，请使用 get_instance() 方法获取实例")
        
        # 服务字典，键为服务类型，值为服务实例
        self._services: Dict[Type, Any] = {}
        
        # 获取日志记录器
        self.logger = Logger.get_logger("service_locator")
        
        # 设置单例实例
        ServiceLocator._instance = self
    
    def register_service(self, service_type: Type[T], service_instance: T) -> None:
        """
        注册服务
        
        @param service_type: 服务类型
        @param service_instance: 服务实例
        """
        # 检查服务是否已经注册
        if service_type in self._services:
            existing_instance = self._services[service_type]
            # 如果是同一个实例，则跳过
            if existing_instance is service_instance:
                self.logger.debug(f"服务已注册且为同一实例，跳过: {service_type.__name__}")
                return
            # 如果是不同实例，则记录警告并替换
            else:
                self.logger.warning(f"服务已注册但为不同实例，将替换: {service_type.__name__}")
        
        # 注册服务
        self._services[service_type] = service_instance
        self.logger.debug(f"注册服务: {service_type.__name__}")
    
    def get_service(self, service_type: Type[T]) -> Optional[T]:
        """
        获取服务
        
        @param service_type: 服务类型
        @return: 服务实例，如果不存在则返回 None
        """
        service = self._services.get(service_type)
        if service is None:
            self.logger.warning(f"服务不存在: {service_type.__name__}")
        return service
    
    def get_service_by_type(self, service_type: Type[T]) -> T:
        """
        根据类型获取服务，如果不存在则抛出异常
        
        @param service_type: 服务类型
        @return: 服务实例
        @raises KeyError: 如果服务不存在
        """
        service = self.get_service(service_type)
        if service is None:
            raise KeyError(f"服务不存在: {service_type.__name__}")
        return service
    
    def unregister_service(self, service_type: Type) -> None:
        """
        注销服务
        
        @param service_type: 服务类型
        """
        if service_type in self._services:
            del self._services[service_type]
            self.logger.debug(f"注销服务: {service_type.__name__}")
    
    def clear(self) -> None:
        """
        清除所有服务
        """
        self._services.clear()
        self.logger.debug("清除所有服务")